package com.anno.test.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

@SpringBootApplication
@Description(desc="SpringBoot run class annotaion desc",age=10)
public class DemoApplication {

    @Description(desc="main method annotaion desc",age=1)
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);

        try {
            //1 使用类加载器加载类
            Class clazz = Class.forName("com.anno.test.demo.TestAnno");
            //2 找到类上面的注解
            boolean isExistAnno = clazz.isAnnotationPresent(Description.class);
            if(isExistAnno){
                //2.1 拿到注解实例
                Description description = (Description) clazz.getAnnotation(Description.class);
                //2.2 获取注解值
                System.out.println(description.desc()+"   "+ description.age());
            }

            //3 找到方法上的注解
            Method[] methods = clazz.getMethods();
            for (Method method:methods) {
                boolean isMethodExistAnno = method.isAnnotationPresent(Description.class);
                if(isMethodExistAnno){
                    //3.1 拿到注解实例
                    Description description = (Description) method.getAnnotation(Description.class);
                    //3.2 获取注解值
                    System.out.println(description.desc()+"   "+ description.age());
                }
            }

            //4 另一中方式获取方法上的注解
            for(Method method :methods){
                Annotation[] ans = method.getAnnotations();
                for(Annotation an:ans){
                    if(an instanceof Description){
                        Description description = (Description)an;
                        System.out.println(description.desc()+"   "+ description.age());
                    }
                }
            }

            //5 注解实战
            testAnno();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void testAnno()  throws Exception {
        UserFilter filter1 = new UserFilter();
        filter1.setId(100);

        UserFilter filter2 = new UserFilter();
        filter2.setName("jack");

        UserFilter filter3 = new UserFilter();
        filter3.setEmail("abc@163.com,111@qq.com");

        String sql1 = query(filter1);
        String sql2 = query(filter2);
        String sql3 = query(filter3);

        System.out.println(sql1);
        System.out.println(sql2);
        System.out.println(sql3);
    }

    public static String query(UserFilter filter) throws Exception {
        StringBuffer sb = new StringBuffer();
        //1 获取UserFilter类类型
        Class clazz = Class.forName("com.anno.test.demo.UserFilter");
        //2 获取table的名称
        boolean isExistTableAnno = clazz.isAnnotationPresent(Table.class);
        if(isExistTableAnno){
            Table table = (Table)clazz.getAnnotation(Table.class);
            String tableName = table.value();
            sb.append("select * from ").append(tableName).append(" where 1=1 ");
        }
        //3 遍历所有字段
        Field[] fields = clazz.getDeclaredFields();
        for(Field field:fields){
            //获取字段名称及值
            boolean isExistColumnAnno = field.isAnnotationPresent(Column.class);
            if(isExistColumnAnno){
                Column column = field.getAnnotation(Column.class);
                String columnName = column.value();
                //拼装get属性方法
                String fieldName = field.getName();
                String getMethodName = "get"+fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
                Method getMethod = clazz.getMethod(getMethodName);
                Object fieldValueObj = getMethod.invoke(filter);
                if(fieldValueObj == null || (fieldValueObj instanceof Long && (Long)fieldValueObj==0))
                    continue;
                sb.append(" and ").append(columnName);
                if(fieldValueObj instanceof String) {
                    if(((String) fieldValueObj).contains(",")){
                        String[] values = ((String) fieldValueObj).split(",");
                        sb.append(" in(");
                        for(String v:values){
                            sb.append("'").append(v).append("'").append(",");
                        }
                        sb.deleteCharAt(sb.length()-1);
                        sb.append(")");
                    }else{
                        sb.append("='").append(fieldValueObj).append("'");
                    }
                }else if(fieldValueObj instanceof Long){
                    sb.append("=").append(fieldValueObj);
                }
            }
        }
        return  sb.toString();
    }
}
